import Foundation

public struct StaticRegistrationWorkDoneProgressTextDocumentRegistrationOptions: Codable, Hashable,
	Sendable
{
	public var workDoneProgress: Bool?
	public var textDocument: TextDocumentIdentifier
	public var position: Position
	public var documentSelector: DocumentSelector?
	public var id: String?

	public init(
		workDoneProgress: Bool? = nil,
		textDocument: TextDocumentIdentifier,
		position: Position,
		documentSelector: DocumentSelector? = nil,
		id: String? = nil
	) {
		self.workDoneProgress = workDoneProgress
		self.textDocument = textDocument
		self.position = position
		self.documentSelector = documentSelector
		self.id = id
	}
}

public struct PartialResultsWorkDoneProgressTextDocumentRegistrationOptions: Codable, Hashable,
	Sendable
{
	public var workDoneProgress: Bool?
	public var textDocument: TextDocumentIdentifier
	public var position: Position
	public var documentSelector: DocumentSelector?
	public var partialResultToken: ProgressToken?

	public init(
		workDoneProgress: Bool? = nil,
		textDocument: TextDocumentIdentifier,
		position: Position,
		documentSelector: DocumentSelector? = nil,
		partialResultToken: ProgressToken? = nil
	) {
		self.workDoneProgress = workDoneProgress
		self.textDocument = textDocument
		self.position = position
		self.documentSelector = documentSelector
		self.partialResultToken = partialResultToken
	}
}

public struct WorkDoneProgressOptions: Codable, Hashable, Sendable {
	public var workDoneProgress: Bool?

	public init(workDoneProgress: Bool? = nil) {
		self.workDoneProgress = workDoneProgress
	}
}

public struct SaveOptions: Codable, Hashable, Sendable {
	public let includeText: Bool?

	public init(includeText: Bool? = nil) {
		self.includeText = includeText
	}
}

public enum TextDocumentSyncKind: Int, Codable, Hashable, Sendable {
	case none = 0
	case full = 1
	case incremental = 2
}

public struct TextDocumentSyncOptions: Codable, Hashable, Sendable {
	public var openClose: Bool?
	public var change: TextDocumentSyncKind?
	public var willSave: Bool?
	public var willSaveWaitUntil: Bool?
	public var save: TwoTypeOption<Bool, SaveOptions>?

	public var effectiveSave: SaveOptions? {
		switch save {
		case nil:
			return nil
		case .optionA(let value):
			return value ? SaveOptions(includeText: false) : nil
		case .optionB(let options):
			return options
		}
	}

	public init(
		openClose: Bool? = nil, change: TextDocumentSyncKind? = nil, willSave: Bool? = nil,
		willSaveWaitUntil: Bool? = nil, save: TwoTypeOption<Bool, SaveOptions>? = nil
	) {
		self.openClose = openClose
		self.change = change
		self.willSave = willSave
		self.willSaveWaitUntil = willSaveWaitUntil
		self.save = save
	}

}

public struct CompletionOptions: Codable, Hashable, Sendable {
	public struct CompletionItem: Codable, Hashable, Sendable {
		public var labelDetailsSupport: Bool?

		public init(labelDetailsSupport: Bool?) {
			self.labelDetailsSupport = labelDetailsSupport
		}
	}

	public var workDoneProgress: Bool?
	public var triggerCharacters: [String]?
	public var allCommitCharacters: [String]?
	public var resolveProvider: Bool?
	public var completionItem: CompletionItem?

	public init(
		workDoneProgress: Bool,
		triggerCharacters: [String]?,
		allCommitCharacters: [String]?,
		resolveProvider: Bool,
		completionItem: CompletionItem?
	) {
		self.workDoneProgress = workDoneProgress
		self.triggerCharacters = triggerCharacters
		self.allCommitCharacters = allCommitCharacters
		self.resolveProvider = resolveProvider
		self.completionItem = completionItem
	}
}

public typealias HoverOptions = WorkDoneProgressOptions

public struct SignatureHelpOptions: Codable, Hashable, Sendable {
	public var workDoneProgress: Bool?
	public var triggerCharacters: [String]?
	public var retriggerCharacters: [String]?

	public init(
		workDoneProgress: Bool? = nil,
		triggerCharacters: [String]? = nil,
		retriggerCharacters: [String]? = nil
	) {
		self.workDoneProgress = workDoneProgress
		self.triggerCharacters = triggerCharacters
		self.retriggerCharacters = retriggerCharacters
	}
}

public typealias DeclarationOptions = WorkDoneProgressOptions

public typealias DeclarationRegistrationOptions =
	StaticRegistrationWorkDoneProgressTextDocumentRegistrationOptions

public typealias DefinitionOptions = WorkDoneProgressOptions

public typealias TypeDefinitionOptions = WorkDoneProgressOptions

public typealias TypeDefinitionRegistrationOptions =
	PartialResultsWorkDoneProgressTextDocumentRegistrationOptions

public typealias ImplementationOptions = WorkDoneProgressOptions

public typealias ImplementationRegistrationOptions =
	StaticRegistrationWorkDoneProgressTextDocumentRegistrationOptions

public typealias ReferenceOptions = WorkDoneProgressOptions

public struct DocumentSymbolOptions: Codable, Hashable, Sendable {
	public var workDoneProgress: Bool?
	public var label: String?

	public init(workDoneProgress: Bool? = nil, label: String? = nil) {
		self.workDoneProgress = workDoneProgress
		self.label = label
	}
}

public typealias DocumentColorOptions = WorkDoneProgressOptions

public typealias DocumentColorRegistrationOptions =
	StaticRegistrationWorkDoneProgressTextDocumentRegistrationOptions

public typealias DocumentFormattingOptions = WorkDoneProgressOptions

public typealias DocumentRangeFormattingOptions = WorkDoneProgressOptions

public struct DocumentOnTypeFormattingOptions: Codable, Hashable, Sendable {
	public var firstTriggerCharacter: String
	public var moreTriggerCharacter: [String]?

	public init(
		firstTriggerCharacter: String,
		moreTriggerCharacter: [String]? = nil
	) {
		self.firstTriggerCharacter = firstTriggerCharacter
		self.moreTriggerCharacter = moreTriggerCharacter
	}
}

public typealias FoldingRangeOptions = WorkDoneProgressOptions

public typealias FoldingRangeRegistrationOptions =
	StaticRegistrationWorkDoneProgressTextDocumentRegistrationOptions

public typealias LinkedEditingRangeOptions = WorkDoneProgressOptions

public typealias LinkedEditingRangeRegistrationOptions =
	StaticRegistrationWorkDoneProgressTextDocumentRegistrationOptions

public struct SemanticTokensOptions: Codable, Hashable, Sendable {
	public var workDoneProgress: Bool?
	public var legend: SemanticTokensLegend
	public var range: SemanticTokensClientCapabilities.Requests.RangeOption?
	public var full: SemanticTokensClientCapabilities.Requests.FullOption?

	public init(
		workDoneProgress: Bool? = nil, legend: SemanticTokensLegend,
		range: SemanticTokensClientCapabilities.Requests.RangeOption? = nil,
		full: SemanticTokensClientCapabilities.Requests.FullOption? = nil
	) {
		self.workDoneProgress = workDoneProgress
		self.legend = legend
		self.range = range
		self.full = full
	}
}

public struct SemanticTokensRegistrationOptions: Codable, Hashable, Sendable {
	public var documentSelector: DocumentSelector?
	public var workDoneProgress: Bool?
	public var legend: SemanticTokensLegend
	public var range: SemanticTokensClientCapabilities.Requests.RangeOption?
	public var full: SemanticTokensClientCapabilities.Requests.FullOption?
	public var id: String?

	public init(
		documentSelector: DocumentSelector? = nil, workDoneProgress: Bool? = nil,
		legend: SemanticTokensLegend,
		range: SemanticTokensClientCapabilities.Requests.RangeOption? = nil,
		full: SemanticTokensClientCapabilities.Requests.FullOption? = nil, id: String? = nil
	) {
		self.documentSelector = documentSelector
		self.workDoneProgress = workDoneProgress
		self.legend = legend
		self.range = range
		self.full = full
		self.id = id
	}
}

public typealias MonikerOptions = WorkDoneProgressOptions

public typealias MonikerRegistrationOptions =
	PartialResultsWorkDoneProgressTextDocumentRegistrationOptions

public struct WorkspaceFoldersServerCapabilities: Codable, Hashable, Sendable {
	public var supported: Bool?
	public var changeNotifications: TwoTypeOption<String, Bool>?

	public init(
		supported: Bool? = nil,
		changeNotifications: TwoTypeOption<String, Bool>? = nil
	) {
		self.supported = supported
		self.changeNotifications = changeNotifications
	}
}

public struct ServerCapabilities: Codable, Hashable, Sendable {
	public struct Workspace: Codable, Hashable, Sendable {
		public struct FileOperations: Codable, Hashable, Sendable {
			public var didCreate: FileOperationRegistrationOptions?
			public var willCreate: FileOperationRegistrationOptions?
			public var didRename: FileOperationRegistrationOptions?
			public var willRename: FileOperationRegistrationOptions?
			public var didDelete: FileOperationRegistrationOptions?
			public var willDelete: FileOperationRegistrationOptions?

			public init(
				didCreate: FileOperationRegistrationOptions? = nil,
				willCreate: FileOperationRegistrationOptions? = nil,
				didRename: FileOperationRegistrationOptions? = nil,
				willRename: FileOperationRegistrationOptions? = nil,
				didDelete: FileOperationRegistrationOptions? = nil,
				willDelete: FileOperationRegistrationOptions? = nil
			) {
				self.didCreate = didCreate
				self.willCreate = willCreate
				self.didRename = didRename
				self.willRename = willRename
				self.didDelete = didDelete
				self.willDelete = willDelete
			}
		}

		public var workspaceFolders: WorkspaceFoldersServerCapabilities?
		public var fileOperations: FileOperations?

		public init(
			workspaceFolders: WorkspaceFoldersServerCapabilities? = nil,
			fileOperations: FileOperations? = nil
		) {
			self.workspaceFolders = workspaceFolders
			self.fileOperations = fileOperations
		}
	}

	public var textDocumentSync: TwoTypeOption<TextDocumentSyncOptions, TextDocumentSyncKind>?
	public var completionProvider: CompletionOptions?
	public var hoverProvider: TwoTypeOption<Bool, HoverOptions>?
	public var signatureHelpProvider: SignatureHelpOptions?
	public var declarationProvider:
		ThreeTypeOption<Bool, DeclarationOptions, DeclarationRegistrationOptions>?
	public var definitionProvider: TwoTypeOption<Bool, DefinitionOptions>?
	public var typeDefinitionProvider:
		ThreeTypeOption<Bool, TypeDefinitionOptions, TypeDefinitionRegistrationOptions>?
	public var implementationProvider:
		ThreeTypeOption<Bool, ImplementationOptions, ImplementationRegistrationOptions>?
	public var referencesProvider: TwoTypeOption<Bool, ReferenceOptions>?
	public var documentHighlightProvider: TwoTypeOption<Bool, DocumentHighlightOptions>?
	public var documentSymbolProvider: TwoTypeOption<Bool, DocumentSymbolOptions>?
	public var codeActionProvider: TwoTypeOption<Bool, CodeActionOptions>?
	public var codeLensProvider: CodeLensOptions?
	public var documentLinkProvider: DocumentLinkOptions?
	public var colorProvider:
		ThreeTypeOption<Bool, DocumentColorOptions, DocumentColorRegistrationOptions>?
	public var documentFormattingProvider: TwoTypeOption<Bool, DocumentFormattingOptions>?
	public var documentRangeFormattingProvider: TwoTypeOption<Bool, DocumentRangeFormattingOptions>?
	public var documentOnTypeFormattingProvider: DocumentOnTypeFormattingOptions?
	public var renameProvider: TwoTypeOption<Bool, RenameOptions>?
	public var foldingRangeProvider:
		ThreeTypeOption<Bool, FoldingRangeOptions, FoldingRangeRegistrationOptions>?
	public var executeCommandProvider: ExecuteCommandOptions?
	public var selectionRangeProvider:
		ThreeTypeOption<Bool, SelectionRangeOptions, SelectionRangeRegistrationOptions>?
	public var linkedEditingRangeProvider:
		ThreeTypeOption<Bool, LinkedEditingRangeOptions, LinkedEditingRangeRegistrationOptions>?
	public var callHierarchyProvider:
		ThreeTypeOption<Bool, CallHierarchyOptions, CallHierarchyRegistrationOptions>?
	public var semanticTokensProvider:
		TwoTypeOption<SemanticTokensOptions, SemanticTokensRegistrationOptions>?
	public var monikerProvider: ThreeTypeOption<Bool, MonikerOptions, MonikerRegistrationOptions>?
	public var typeHierarchyProvider:
		ThreeTypeOption<Bool, TypeHierarchyOptions, TypeHierarchyRegistrationOptions>?
	public var inlayHintProvider:
		ThreeTypeOption<Bool, InlayHintOptions, InlayHintRegistrationOptions>?
	public var diagnosticProvider: TwoTypeOption<DiagnosticOptions, DiagnosticRegistrationOptions>?
	public var workspaceSymbolProvider: TwoTypeOption<Bool, WorkspaceSymbolOptions>?
	public var workspace: Workspace?
	public var experimental: LSPAny?

	public init() {
	}
}
